package com.znsd.zl.app.wechat.service.impl;

import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.znsd.zl.app.wechat.config.WeChatPayConfig;
import com.znsd.zl.app.wechat.service.IWeChatPayService;
import com.znsd.zl.app.wechat.utils.WeChatConstants;
import com.znsd.zl.app.wechat.utils.WeChatPayUtils;
import com.znsd.zl.app.wechat.vo.req.WeChatPayReqVO;
import com.znsd.zl.exception.RRException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 *      微信支付统一下单接口实现类
 * </p>
 *
 * @ClassName WeChatPayServiceImpl
 * @Description TODO
 * @Author jaypdd
 * @Date 2020/8/28 15:01
 * @Version v1.0
 */
@Service
@Slf4j
public class WeChatPayServiceImpl implements IWeChatPayService {

	@Resource
	WeChatPayUtils payUtils;

	@Resource
	private WeChatPayConfig payConfig;

	/**
	 * 微信支付统一下单二次验签
	 * @param reqVO 微信支付下单请求参数vo对象
	 * @return      返回小程序唤起微信支付必备5个参数
	 * @throws Exception 支付失败
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Map<String, String> appPay(WeChatPayReqVO reqVO) throws Exception {
		// 生成商户订单
		Map<String, String> map = new HashMap<>(1);
		map.put("nonce_str", WXPayUtil.generateNonceStr());
		map.put("body", "租房-北京四合院");
		map.put("out_trade_no", reqVO.getOrderNo());
		map.put("total_fee", String.valueOf(Math.round((reqVO.getMoney() * 100))));
		map.put("appid", payConfig.getAppId());
		map.put("openid", reqVO.getOpenId());
		map.put("mch_id", payConfig.getMchId());
		map.put("spbill_create_ip", WeChatPayConfig.LOCAL_IP);
		map.put("trade_type", payConfig.getTradeType());
		map.put("notify_url", payConfig.getNotifyUrl());
		// 签名
		map.put("sign", WXPayUtil.generateSignature(map, payConfig.getMchKey()));
		// 调用支付统一下单接口，获取预付订单信息
		Map<String, String> resultMap = payUtils.unifiedOrder(map);

		// 组合返回的预付订单信息数据，进行二次签名，返回5个参数给app唤起微信支付
		if ( WeChatConstants.SUCCESS.equals(resultMap.get(WeChatConstants.SUCCESS_CODE))
				&& WeChatConstants.MSG.equals(resultMap.get(WeChatConstants.SUCCESS_MSG)) ) {
			Map<String, String> respData = new HashMap<>(1);
			respData.put("appId", payConfig.getAppId());
			respData.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
			respData.put("nonceStr", WXPayUtil.generateNonceStr());
			respData.put("signType", WXPayConstants.MD5);
			respData.put("package", "prepay_id=" + resultMap.get("prepay_id"));
			String sign = WXPayUtil.generateSignature(respData, payConfig.getMchKey());
			respData.put("paySign", sign);
			log.info("【小程序支付】统一下单成功，参数：{}", resultMap.toString());
			return respData;
		}else{
			log.error("【小程序支付】统一下单失败，失败原因：{}", resultMap.toString());
			throw new RRException("支付失败");
		}
	}

}
